package main

import (
	"fmt"
	"net"
	"strings"
)

type User struct {
	Name string
	Addr string
	C    chan string
	conn net.Conn

	server *Server
}

func NewUser(conn net.Conn, server *Server) *User {
	userAddr := conn.RemoteAddr().String()
	user := &User{
		Name:   userAddr, // 默认名字
		Addr:   userAddr,
		C:      make(chan string),
		conn:   conn,
		server: server,
	}

	go user.ListenAndSend()

	return user
}

// 重管道中获取数据，发送给用户
func (u *User) ListenAndSend() {
	for {
		msg := <-u.C
		u.conn.Write([]byte(msg + "\n"))
	}
}

// 用户上线
func (u *User) Online() {
	u.server.mapLock.Lock()
	u.server.OnlineMap[u.Name] = u
	u.server.mapLock.Unlock()

	u.server.Broadcast(u, "已上线")
}

// 用户下线
func (u *User) Offline() {
	u.server.mapLock.Lock()
	delete(u.server.OnlineMap, u.Name)
	u.server.mapLock.Unlock()

	u.server.Broadcast(u, "已下线")
}

func (u *User) SendMsg(msg string) {
	u.conn.Write([]byte(msg))
}

// 用户处理消息
func (u *User) DoMessage(msg string) {
	// 客户端输入who,显示所有在线用户
	if msg == "who" {
		u.server.mapLock.Lock()
		for _, user := range u.server.OnlineMap {
			msg := fmt.Sprintf("[%s](状态: 在线)\n", user.Name)
			u.SendMsg(msg)
		}
		u.server.mapLock.Unlock()
	} else if len(msg) > 7 && msg[:7] == "rename|" {
		newName := strings.Split(msg, "|")[1]

		_, ok := u.server.OnlineMap[newName]
		if ok {
			u.SendMsg(fmt.Sprintf(`"%s"已经被使用`, newName))
		} else {
			u.server.mapLock.Lock()
			// 删除旧的用户名
			delete(u.server.OnlineMap, u.Name)
			u.server.OnlineMap[newName] = u
			u.server.mapLock.Unlock()

			u.Name = newName
			u.SendMsg(fmt.Sprintf("用户名更改为：%s\n", u.Name))
		}
	} else if len(msg) > 4 && msg[:3] == "to|" {
		// 消息格式: to|alice|content

		// 获取对方的用户名
		msgSlice := strings.Split(msg, "|")
		remoteName := msgSlice[1]
		if remoteName == "" {
			u.SendMsg("消息格式不正确,请使用\"to|张三|你好！\"格式\n")
			return
		}

		// 根据用户名得到User对象
		remoteUser, ok := u.server.OnlineMap[remoteName]
		if !ok {
			u.SendMsg(fmt.Sprintf("用户名\"%s\"", remoteName))
			return
		}

		content := msgSlice[2]
		if content == "" {
			u.SendMsg("消息不能为空，请重发")
			return
		}

		// 获取消息内容，通过对方的User对象将消息发送过去
		remoteUser.SendMsg(fmt.Sprintf("%s对您说：%s", u.Name, content))

	} else {
		u.server.Broadcast(u, msg)
	}
}
